package demo.annotation;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class JsonSerializer {
    public static String serialize(Object object) throws IllegalAccessException {
        Class<?> objectClass = object.getClass();
        Map<String, String> jsonElements = new HashMap<>();
        for (Field field : objectClass.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(JsonField.class)) {
                jsonElements.put(getSerializedKey(field), (String) field.get(object));
            }
        }
        // return toJsonString(jsonElements);
        return convertToJsonString(jsonElements);
    }

    private static String getSerializedKey(Field field) {
        String annotationValue = field.getAnnotation(JsonField.class).value();
        if (annotationValue.isEmpty()) {
            return field.getName();
        } else {
            return annotationValue;
        }
    }

    private static String toJsonString(Map<String, String> jsonMap) {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
            builder.append(entry.getKey()).append(": \"").append(entry.getValue()).append("\", ");
        }
        // 删除最后一个逗号
        builder.delete(builder.length() - 2, builder.length());
        String elementsString = builder.toString();
        return "{" + elementsString + "}";
    }


    private static String convertToJsonString(Map<String, String> jsonMap) {
        Stream<Map.Entry<String, String>> stream = jsonMap.entrySet().stream();
        Function<Map.Entry<String, String>, String> mapper = new JsonSerializer.EntryToStringFunction();
        Stream<String> mapStream = stream.map(mapper);
        String elementsString = mapStream.collect(Collectors.joining(", "));
        return "{" + elementsString + "}";
    }

    /*
     * 嵌套类实现函数式接口
     */
    private static class EntryToStringFunction implements Function<Map.Entry<String, String>, String> {
        @Override
        public String apply(Map.Entry<String, String> entry) {
            return entry.getKey() + ": \"" + entry.getValue() + "\"";
        }
    }
}

